#include "ColorShader.h"
#include "Device.h"
#include "Camera.h"
#include "Model.h"

#include "NeroGame\NDirector.h"
#include <d3dx11async.h>

using namespace Graphics;

RTTI_DEFINITIONS(ColorShader)

ColorShader::ColorShader(void)
	:Shader("ColorShader","")
{
}

ColorShader::~ColorShader(void)
{
	Deinitialize();
}

bool ColorShader::Initialize()
{
	Graphics::D3DDevice* device = GetPlatform()->GetDevice()->As<Graphics::D3DDevice>();
	bool result = InitializeShader(	device->GetWindowsSettings().WindowHandle, 
									"..\\..\\assets\\shaders\\color.vs", 
									"..\\..\\assets\\shaders\\color.ps");
	return result;
}

void ColorShader::Deinitialize()
{
	DeinitializeShader();
}

bool ColorShader::Render(int indexCount, D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix)
{
	Graphics::D3DDevice* device = GetPlatform()->GetDevice()->As<Graphics::D3DDevice>();

	bool result = Shader::SetShaderParameters(device, worldMatrix, viewMatrix, projectionMatrix);

	result = RenderShader(device, indexCount);

	return result;
}

bool ColorShader::InitializeShader(HWND hwnd, const char* vsFilename, const char* psFilename)
{
	Graphics::D3DDevice* device = GetPlatform()->GetDevice()->As<Graphics::D3DDevice>();
	if(Shader::InitializeShader(device, hwnd, vsFilename, psFilename))
	{
		// Now setup the layout of the data that goes into the shader.
		// This setup needs to match the VertexType stucture in the ModelClass and in the shader.
		D3D11_INPUT_ELEMENT_DESC polygonLayout[2];
		polygonLayout[0].SemanticName = "POSITION";
		polygonLayout[0].SemanticIndex = 0;
		polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
		polygonLayout[0].InputSlot = 0;
		polygonLayout[0].AlignedByteOffset = 0;
		polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		polygonLayout[0].InstanceDataStepRate = 0;

		polygonLayout[1].SemanticName = "COLOR";
		polygonLayout[1].SemanticIndex = 0;
		polygonLayout[1].Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
		polygonLayout[1].InputSlot = 0;
		polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
		polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		polygonLayout[1].InstanceDataStepRate = 0;

		// Get a count of the elements in the layout.
		unsigned int numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);

		// Create the vertex input layout.
		HRESULT result = device->GetDevice()->CreateInputLayout( polygonLayout, 
																numElements, 
																mVertexShaderBuffer->GetBufferPointer(), 
																mVertexShaderBuffer->GetBufferSize(), 
																&mLayout);
		CHECK(result);

		// Release the vertex shader buffer and pixel shader buffer since they are no longer needed.
		mVertexShaderBuffer->Release();
		mVertexShaderBuffer = NULL;

		mPixelShaderBuffer->Release();
		mPixelShaderBuffer = NULL;
	
		return true;
	}
	return false;
}

void ColorShader::DeinitializeShader()
{
	Shader::DeinitializeShader();
}